<?php
/**
 * 事务处理，防止事务重复创建
 *      不适用于多线程
 * 一搬使用方法
 *      Transaction::start();
 *      Transaction::commit();
 *      Transaction::rollback();
 * 多层调用，防止事务重复
 *      在最外层的事务开启位置设置一个‘$name’，只有传入该‘$name’的start($name)/commit($name)/rollback($name)才会被执行
 *      Transaction::setName($name);
 *      Transaction::start($name);
 *          循环体内的事务检测到已开启，并且与已创建事务的‘$name’不同，那么不会重复 start/commit/rollback
 *          Transaction::start($other_name);
 *          Transaction::commit($other_name);
 *          Transaction::rollback($other_name);
 *      Transaction::commit($name);
 *      Transaction::rollback($name);
 */
namespace App\Services\common;

use Illuminate\Support\Facades\{DB, Log};

class Transaction
{
    private static $started = false;
    private static $tran_name;

    public static function isStart()
    {
        return self::$started;
    }

    /**
     * 设置一个事务名
     *
     * @param string $name
     * @return void
     */
    public static function setName(string $name)
    {
        self::$tran_name = $name;
    }

    /**
     * 能进行事务操作吗？
     * @param string $name  [事务名，默认空]
     * @return boolean      [true:能, false:不能]
     */
    public static function canTransaction(string $name = ''): bool
    {
        if(self::$tran_name == $name) {
            return true;
        } else {
            return false;
        }
    }

    public static function start(string $name = '')
    {
        if(self::canTransaction($name) && !self::$started) {
            //DB::beginTransaction();
            self::$started = true;
            #Log::info('[事务][start][do]', ['started'=>self::$started, 'name' => self::$tran_name]);
        }
    }

    public static function commit(string $name = '')
    {
        if(self::canTransaction($name)) {
            #Log::info('[事务][commit][do]', ['started'=>self::$started, 'name' => self::$tran_name]);
            //DB::commit();
        }
    }

    public static function rollBack(string $name = '')
    {
        if(self::canTransaction($name)) {
            #Log::info('[事务][rollback][do]', ['started'=>self::$started, 'name' => self::$tran_name]);
            //DB::rollBack();
        }
    }
}